package kz.edu.sdu.itech.pcs.server;

import kz.edu.sdu.itech.pcs.common.Alphabet;
import kz.edu.sdu.itech.pcs.common.Client;
import kz.edu.sdu.itech.pcs.common.Permutations;
import kz.edu.sdu.itech.pcs.common.ServerStatus;

import org.apache.log4j.Logger;

public class ServerJob extends Thread implements Runnable {
   static Logger log = Logger.getLogger(ServerJob.class);
   Server server;

   Alphabet alphabet = new Alphabet();
   int len = 0;
   int hash;

   double done = 0;
   int count = 0;

   public ServerJob(Server server) {
      this.server = server;
   }

   public Server getServer() {
      return server;
   }

   public void setServer(Server server) {
      this.server = server;
   }

   public Alphabet getAlphabet() {
      return alphabet;
   }

   public void setAlphabet(Alphabet alphabet) {
      this.alphabet = alphabet;
   }

   public int getLen() {
      return len;
   }

   public void setLen(int len) {
      this.len = len;
   }

   public int getHash() {
      return hash;
   }

   public void setHash(int hash) {
      this.hash = hash;
   }

   public void stopWork() {
      server.status = ServerStatus.STOPPING;
      for (Worker w : server.getWorkerSet()) {
         w.stopWork();
      }
   }

   public void count() {
      double sum = 0;
      int cnt = 0;
      for (Worker w : server.getWorkerSet()) {
         sum += w.getPercentage();
         cnt += w.getCount();
      }
      if (server.getWorkerSet().size() != 0) {
         done = sum / server.getWorkerSet().size();
      } else
         done = 0;
      count = cnt;
   }

   public double getDonePercentage() {
      return done;
   }

   public int getCount() {
      return count;
   }

   @Override
   public void run() {
      log.debug("start job: " + toString());
      server.acceptClients(false);
      server.list();

      int n = server.getWorkerSet().size();
      long total = Permutations.getPnm(len, alphabet.size());
      long each = total / n;
      long start = 1;
      long end = Math.min(total, start + each);
      for (Worker w : server.getWorkerSet()) {
         w.setAlphabet(alphabet);
         w.setStart(start);
         w.setEnd(end);
         w.setLen(len);
         w.setHash(hash);
         start = end + 1;
         end = Math.min(total, start + each);
      }
      server.list();

      for (Worker w : server.getWorkerSet()) {
         w.startWork();
      }
      server.status = ServerStatus.RUNNING;
      boolean ok = false;
      boolean alldone = true;
      while (!AppProps.DONE && !ok) {
         ok = true;
         for (Worker w : server.getWorkerSet()) {
            if (w.getStatus().equals(Client.WORKING)) {
               ok = false;
//               break;
            }
            if (!w.getStatus().equals(Client.DONE)) {
               alldone = false;
            }
         }
      }
      if (alldone) {
         server.status = ServerStatus.FINISHED;
      } else {
         server.status = ServerStatus.STOPPED;
      }
      server.list();
      server.acceptClients(true);
   }
}
